import requests
import hashlib
import random
import json
import time
import logging
from pathlib import Path
from typing import List, Dict, Optional

# ====================== 配置区域 ======================
#TODO:
CURSEFORGE_API_KEY = '$2a$10$nMm0xrd5HDAiEmee1B0x2.K0.Mgnm7jjAcpFU0HXVBuEFUiqFyuGG' 
# CurseForge平台认证密钥
CURSEFORGE_API_URL = "https://api.curseforge.com/v1/mods/search"
# 整合包搜索接口地址
BAIDU_APP_ID = '20250217002275861'
# 百度翻译开放平台应用ID
BAIDU_SECRET_KEY = '0Hwnep0zxkipYVQfHAdf'
# 百度翻译密钥
BAIDU_TRANSLATE_URL = "https://fanyi-api.baidu.com/api/trans/vip/translate"
# 百度翻译API端点

# ====================== 优化部分开始 ======================

# ====================== 翻译缓存管理模块 ======================
#TODO:
class EnhancedTranslator:
    def __init__(self):
        self.cache_path = Path('translation_cache.json')
        self.cache = self._load_cache()
        # 智能翻译器：实现带缓存的翻译服务，具备错误恢复和重试机制
    def _load_cache(self) -> Dict:
        """增强型缓存加载，带错误恢复机制"""
        try:
            if self.cache_path.exists():
                with open(self.cache_path, 'r', encoding='utf-8') as f:
                    return json.load(f)
        except (json.JSONDecodeError, IOError) as e:
            logging.warning(f"缓存加载失败已重置: {str(e)}")
            backup_path = self.cache_path.with_suffix('.bak')
            self.cache_path.rename(backup_path)
            logging.warning(f"原缓存已备份至: {backup_path}")
        return {}
        #缓存加载：优先读取本地翻译缓存，失败时自动备份并重建
    def _save_cache(self):
        """原子化保存缓存"""
        temp_path = self.cache_path.with_suffix('.tmp')
        try:
            with open(temp_path, 'w', encoding='utf-8') as f:
                json.dump(self.cache, f, ensure_ascii=False, indent=2)
            temp_path.replace(self.cache_path)
        except Exception as e:
            logging.error(f"缓存保存失败: {str(e)}")

    def safe_translate(self, text: str, max_retry: int = 3) -> str:
        """增强型翻译方法"""
        if not text.strip():
            return ""

        # 哈希缓存键
        cache_key = hashlib.md5(text.encode('utf-8')).hexdigest()
        if cached := self.cache.get(cache_key):
            return cached

        # 智能重试机制
        params = {
            'q': text,
            'from': 'en',
            'to': 'zh',
            'appid': BAIDU_APP_ID,
            'salt': str(random.randint(10000, 99999)),
            'sign': ''
        }
        params['sign'] = hashlib.md5(
            f"{BAIDU_APP_ID}{text}{params['salt']}{BAIDU_SECRET_KEY}".encode()
        ).hexdigest()

        for attempt in range(max_retry):
            try:
                response = requests.get(BAIDU_TRANSLATE_URL, params=params, timeout=5+(attempt*2))
                response.raise_for_status()
                result = response.json()
                
                if 'error_code' in result:
                    error_msg = f"API错误 [{result['error_code']}]: {result['error_msg']}"
                    raise requests.HTTPError(error_msg)
                
                translated = result['trans_result'][0]['dst']
                self.cache[cache_key] = translated
                self._save_cache()
                return translated
                
            except (requests.RequestException, KeyError) as e:
                logging.warning(f"翻译尝试 {attempt+1}/{max_retry} 失败: {str(e)}")
                time.sleep(1.5 ** attempt)  # 指数退避

        logging.error(f"最终翻译失败: {text}")
        self.cache[cache_key] = text  # 缓存原文防止重复尝试
        self._save_cache()
        return text
    
#TODO:#安全翻译：带智能重试、错误降级处理的核心方法
# ====================== 数据获取模块 ====================== 
class CurseForgeAPI:
    #CurseForge API交互模块：封装请求参数和错误处理
    def __init__(self):
        self.session = requests.Session()
        self.session.headers.update({
            "x-api-key": CURSEFORGE_API_KEY,
            "Accept": "application/json"
        })

    def fetch_top_modpacks(self) -> Optional[List[Dict]]:
        """增强型API请求"""
        #获取热门整合包：按人气倒序获取前20个模组包
        params = {
            'gameId': 432,
            'classId': 4471,
            'pageSize': 20,
            'sortOrder': 'desc',
            'sortField': 'popularity'
        }

        try:
            response = self.session.get(CURSEFORGE_API_URL, params=params, timeout=15)
            response.raise_for_status()
            
            if response.status_code == 200:
                data = response.json()
                if not data.get('data'):
                    logging.error("API返回空数据")
                    return None
                return data['data']
                
            logging.error(f"非预期状态码: {response.status_code}")
            return None
            
        except requests.RequestException as e:
            logging.error(f"API请求失败: {str(e)}")
            return None

def validate_data(modpack: Dict) -> bool:
    #'''数据校验：检查必要字段是否存在'''
    """数据校验"""
    required_fields = ['id', 'name', 'downloadCount', 'dateModified']
    if not all(field in modpack for field in required_fields):
        logging.warning(f"数据校验失败: 缺少必要字段")
        return False
    return True

def format_output(data: List[Dict], translator: EnhancedTranslator) -> List[Dict]:
    """结构化输出"""
    #'''结构化处理：翻译关键字段并重组数据结构'''
    processed = []
    for item in data:
        if not validate_data(item):
            continue
            
        try:
            processed.append({
                'id': item['id'],
                'name_en': item['name'],
                'name_zh': translator.safe_translate(item['name']),
                'downloads': item.get('downloadCount', 0),
                'last_updated': item['dateModified'],
                'author': item['authors'][0]['name'] if item.get('authors') else '未知',
                
                'description_zh': translator.safe_translate(item.get('summary', '')[:300]),
                'url': item['links']['websiteUrl'] if item.get('links') else ''
            })
        except KeyError as e:
            logging.error(f"数据处理错误: 缺少关键字段 {str(e)}")
    return processed

def save_results(data: List[Dict], file_path: Path = Path('modpacks.json')):
    """增强型数据保存"""
    #'''持久化存储：带完整性检查的结果保存'''

    try:
        file_path.parent.mkdir(exist_ok=True)
        with open(file_path, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=2, ensure_ascii=False)
            
        logging.info(f"文件已保存至: {file_path.absolute()}")
        logging.info(f"包含 {len(data)} 个整合包")
        
        # 验证文件完整性
        if file_path.stat().st_size < 100:
            raise IOError("生成文件异常，文件大小过小")
            
    except (IOError, PermissionError) as e:
        logging.error(f"文件保存失败: {str(e)}")
        raise

# ====================== 主程序优化 ======================
#TODO:
def main():
     #'''主流程控制：协调各模块协同工作'''
    logging.basicConfig(
        level=logging.INFO,
        format='%(asctime)s - %(levelname)s - %(message)s',
        handlers=[logging.StreamHandler()]
    )

    logging.info("🚀 开始获取热门整合包")
    
    # 初始化组件
    api = CurseForgeAPI()
    translator = EnhancedTranslator()
    
    # 获取数据
    if (raw_data := api.fetch_top_modpacks()) is None:
        logging.error("获取数据失败，请检查API密钥或网络连接")
        return
        
    # 处理数据
    processed_data = format_output(raw_data, translator)
    
    if not processed_data:
        logging.error("无有效数据生成")
        return
    
    # 保存结果
    try:
        save_results(processed_data)
        logging.info("✅ 操作成功完成")
    except Exception:
        logging.error("❌ 程序执行失败")

if __name__ == "__main__":
    main()
